import os, datetime, sqlite3
from ..classes import *


class DBStorage:
	def __init__(self, name, placeholder='?'):
		self.directory = "data/" + name
		self.placeholder = placeholder
		self.load()

	def getInitFields(self):
		return "id integer primary key autoincrement";

	def initTable(self):
		item = LodgerItem()
		fields = self.getInitFields()
		for field, value in item.getData().items():
			if field == "id":
				continue
			fields += f", {field} "
			match value:
				case int():
					fields += "integer"
				case datetime.datetime():
					fields += "timestamp"
				case _:
					fields += "text"
		self.dbc.execute(f"create table if not exists lodger({fields})")

	def load(self):
		if not os.path.exists(self.directory):
			os.makedirs(self.directory)
		self.db = sqlite3.connect(self.directory + '/lodger.sqlite', detect_types=sqlite3.PARSE_DECLTYPES)
		self.db.row_factory = sqlite3.Row
		self.dbc = self.db.cursor()
		self.initTable()

	def store(self):
		self.db.close()

	def clean(self):
		self.dbc.execute(f"delete from lodger")
		self.db.commit()

	def getItem(self, id):
		item = LodgerItem()
		if id > 0:
			self.dbc.execute(f"select * from lodger where id={self.placeholder}", (id,))
			row = self.dbc.fetchone()
			if row:
				item.setData(row)
			else:
				item = None
		return item

	def addItem(self, item):
		names = ""
		values = ""
		params = []
		update = ""
		for field, value in item.getData().items():
			if field == "id":
				continue
			if names:
				names += f", {field}"
				values += f", {self.placeholder}"
				update += f", {field} = {self.placeholder}"
			else:
				names = field
				values = self.placeholder
				update += f"{field} = {self.placeholder}"
			if isinstance(value, datetime.datetime):
				params.append(self.makeTime(value))
			else:
				params.append(value)

		if not item.id or int(item.id) == 0:
			self.dbc.execute(f"insert into lodger({names}) values({values})", params)
		else:
			params.append(item.id)
			self.dbc.execute(f"update lodger set {update} where id={self.placeholder}", params)
		self.db.commit()

	def deleteItem(self, id):
		self.dbc.execute(f"delete from lodger where id={self.placeholder}", (id,))
		self.db.commit()

	def getItems(self):
		self.dbc.execute("select * from lodger order by id desc")
		for r in self.dbc:
			item = LodgerItem()
			item.setData(r)
			yield (item)

	def makeTime(self, time):
		return time
